package com.celesea.auth.core.service;

import com.celesea.auth.core.dao.BaseDao;
import com.celesea.auth.core.entity.BaseEntity;
import com.celesea.auth.core.entity.BusEntity;
import com.celesea.auth.core.util.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;
import tk.mybatis.mapper.mapperhelper.EntityHelper;

import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * 
 * @author Administrator
 * 
 * @param <T>
 */
public abstract class AbstractBaseService<T extends BaseEntity> implements BaseService<T> {
	protected Logger logger = LoggerFactory.getLogger(getClass());

	protected BaseDao<T> baseDao = null;

	protected interface PageProvider<T> {
		Page<T> provider(Filter filter, com.celesea.auth.core.util.Page page,Sort sort);
	}

	/**
	 * 提供到对象
	 * 
	 * @return
	 */
	protected BaseDao<T> dao() {
		if (baseDao == null) {
			Class<?> genericClass = GenericsUtils.getSuperClassGenricType(this.getClass());
			String className = genericClass.getName();
			className = className.replace("entity", "dao") + "Dao";
			try {
				@SuppressWarnings("unchecked")
				Class<? extends BaseDao<T>> daoClass = (Class<? extends BaseDao<T>>) Class.forName(className);
				baseDao = SpringContextHolder.getBean(daoClass);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error(String.format("类【%s】获取Dao接口失败", className));
			}
		}
		return baseDao;
	}

	@Override
	@SuppressWarnings("unchecked")
	public T selectForNew() {
		Class<T> genericClass = GenericsUtils.getSuperClassGenricType(this.getClass());
		String className = genericClass.getName();
		try {
			Class<T> modelClass = (Class<T>) Class.forName(className);
			return modelClass.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(String.format("类【%s】获取Model失败", className));
			return null;
		}
	}

	@Override
	public T selectById(String id) {
		Assert.notNull(id, "查询对象不能为空");
		return dao().selectByPrimaryKey(id);
	}

	@Override
	public T selectForView(String id) {
		return selectById(id);
	}

	@Override
	public T doSave(T entity) {
		if (isInsert(entity)) {
			return insert(entity);
		} else {
			return update(entity);
		}
	}

	@Override
	public T insert(T entity) {
		int result = 0;
		// 业务属性逻辑处理
		if (entity instanceof BusEntity) {
			BusUtil.busAuto((BusEntity) entity);
		}
		entity.setId(generatPk(entity));
//		entity.setVersion(0L);
		result = dao().insert(entity);
		if (result == 0) {
			throw new RuntimeException("保存失败，请重试！");
		}
		return entity;
	}

	@Override
	public T update(T entity) {
		int result = 0;
		// 业务属性逻辑处理
		if (entity instanceof BusEntity) {
			BusUtil.busAuto((BusEntity) entity);
		}
//		Version version = entity.getClass().getAnnotation(Version.class);
//		if (version != null) {
//			Long ver = entity.getVersion();
//			if (ver == null) {
//				ver = 0l;
//			}
//			Example example = new Example(entity.getClass());
//			Criteria criteria1 = example.createCriteria();
//			criteria1.andEqualTo("version", ver).andEqualTo("id", entity.getId());
//			entity.setVersion(ver + 1);
//			result = dao().updateByExample(entity, example);
//		} else {
//			result = dao().updateByPrimaryKey(entity);
//		}
		result = dao().updateByPrimaryKey(entity);
		if (result == 0) {
			throw new RuntimeException("保存失败，请重试！");
		}
		return entity;
	}

	@Override
	public void doDelete(String id) {
		doDeleteMapping(id);
		dao().deleteByPrimaryKey(id);
	}

	@Override
	public void doDeleteMapping(String id) {

	}

	@Override
	public boolean checkUnique(T entity) {
		T result = selectUnique(entity);
		if (result == null) {
			return true;
		} else {
			return result.getId().equals(entity.getId());
		}
	}

	@Override
	public T selectUnique(T entity) {
		Class<?> entityClass = GenericsUtils.getSuperClassGenricType(this.getClass());
		try {
			Example example = new Example(entityClass);
			Criteria criteria = example.createCriteria();
			// 获取全部列
			Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
			// 当某个列有主键策略时，不需要考虑他的属性是否为空，因为如果为空，一定会根据主键策略给他生成一个值
			for (EntityColumn column : columnList) {
				if (column.isId()) {
					continue;
				}
				String property = column.getProperty();
				Object value = BeanUtils.getProperty(entity, property);
				if (value != null) {
					criteria.andEqualTo(property, value);
					System.err.println(property + "=" + value);
				}
			}
			List<T> result = dao().selectByExample(example);
			if (CollectionKit.isEmpty(result)) {
				return null;
			} else {
				return result.get(0);
			}
		} catch (Exception e) {
			logger.info(e.getMessage(), e);
			return null;
		}
	}

	@Override
	public PageData<T> selectPage(Filter filter, com.celesea.auth.core.util.Page page, Sort sort) {
		return selectPageData(filter,page,sort, new PageProvider<T>() {

			@Override
			public Page<T> provider(Filter filter, com.celesea.auth.core.util.Page page, Sort sort) {
//				return (Page<T>) dao().selectPage(filter,page,sort);
				return null;
			}
		});
	}

	protected PageData<T> selectPageData(Filter filter, com.celesea.auth.core.util.Page page,Sort sort, PageProvider<T> provider) {

		PageData<T> data = new PageData<T>();
		// 分页
		if (page != null && page.isCountPage()) {
			PageHelper.startPage(page.getCurrent(), page.getPageSize(), true);
		}
		// 排序
		if (sort != null && sort.isSort()) {
			PageHelper.orderBy(sort.toSort());
		}

		Page<T> pages = provider.provider(filter,page,sort);
		data.setRows(pages.getResult());
		data.setPager(page.toPager(pages.getTotal()));
		data.setFilter(filter);
		data.setSort(sort);
		return data;
	}

	@Override
	public List<T> selectList(Filter filter,Sort sort) {
//		Assert.notNull(queryParam, "参数不能为空");
		// 排序
		if (sort!=null && sort.isSort()) {
			PageHelper.orderBy(sort.toSort());
		}
		return dao().selectPage(filter,null,sort);
	}

	@Override
	public List<T> selectList(Filter filter) {
		return this.selectList(filter,null);
	}

	@Override
	public List<T> selectAll() {
		return dao().selectAll();
	}

	@Override
	public void doDelete(List<String> ids) {
		if (CollectionKit.isNotEmpty(ids)) {
			for (String id : ids) {
				doDelete(id);
			}
		}
	}

	@Override
	public String generatPk(T entity) {
		return UUID.randomUUID().toString();
	}

	/**
	 * 检查是否插入数据
	 * 
	 * @param model
	 * @return
	 */
	protected boolean isInsert(BaseEntity model) {
		return StringKit.isEmpty(model.getId());
	}

	/**
	 * 是否更新
	 * 
	 * @param model
	 * @return
	 */
	protected boolean isUpdate(BaseEntity model) {
		return !isInsert(model);
	}


}
